//
// Created by v on 24-5-15.
//

#include "control_remote_service.h"
#include "utils/rt_print.h"

ControlRemoteService::ControlRemoteService() {
    conn = NULL;
}
ControlRemoteService::~ControlRemoteService() {}

void mg_ws_connect_handler(struct mg_connection *conn, int ev, void *ev_data)
{
    if (ev == MG_EV_OPEN)
    {
        rtdebug("ev connection opened conn=[%p]\n", conn);
        ControlRemoteService *inner = (ControlRemoteService*)conn->fn_data;
        inner->conn = conn;
//        conn->is_hexdumping = 1;
    }
    else if (ev == MG_EV_WS_OPEN)
    {
        rtinfo("Websocket connection opened conn= [%p]\n", conn);
    }
    else if (ev == MG_EV_HTTP_MSG)
    {
        struct mg_http_message *hm = (struct mg_http_message *)ev_data;
        rtinfo("uri [%s] body [%s]", hm->uri.buf, hm->body.buf);
        if (1)
        {
            // Upgrade to websocket. From now on, a connection is a full-duplex
            // Websocket connection, which will receive MG_EV_WS_MSG events.
            //            mg_ws_upgrade(c, hm, NULL);
            //            ws_connection = c;
        }
        else
        {
            // Serve static files
            rterror("Unmanaged request receive\n");
        }
    }
    else if (ev == MG_EV_WS_MSG)
    {
        // Got websocket frame. Received data is wm->data. save it into the Pipe streaming channel
        struct mg_ws_message *wm = (struct mg_ws_message *)ev_data;
        rtinfo("recv data [%d][%s]", wm->data.len, wm->data.buf);
        char end = 0;
    }
    else if (ev == MG_EV_CLOSE)
    {
        rtinfo("Websocket is disconnected");
    }
}

int ControlRemoteService::sendData(std::string &data) {
    if (!conn)
    {
        rterror("conn is not connected");
        return -1;
    }
    int ret = mg_ws_send(conn, data.c_str(), data.length(), 0);
    if (ret < 0)
    {
        rterror("data send failed ret = [%d]", ret);
    }
    else
    {
        rtinfo("send data done ret = [%d]", ret);
    }
    return 0;
}

int ControlRemoteService::start(const char *addr, int port) {
    connAddr = addr;
    connPort = port;
    std::string connUrl = "ws://";
    connUrl += connAddr;
    connUrl += ":";
    connUrl += std::to_string(connPort);
    connUrl += "/control";
    rtdebug("connect to [%s]", connUrl.c_str());

    mg_mgr_init(&mgr);
    mg_log_set(MG_LL_DEBUG);
    conn = mg_ws_connect(&mgr, connUrl.c_str(), mg_ws_connect_handler, this, NULL);
    if (!conn)
    {
        rterror("ws connect failed ");
        return -2;
    }
    rtdebug("conn = [%p]", conn);
    return 0;
}

int ControlRemoteService::stop() {
    mg_mgr_free(&mgr);
    return 0;
}

int ControlRemoteService::doCycle() {
    if (conn)
    {
        mg_mgr_poll(&mgr, 100);
    }
    return 0;
}
